{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Demonstrates some common TensorFlow errors\n",
    "\n",
    "This notebook demonstrates some common TensorFlow errors, how to find them, and how to fix them."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "print(tf.__version__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Shape error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def some_method(data):\n",
    "  a = data[:,0:2]\n",
    "  c = data[:,1]\n",
    "  s = (a + c)\n",
    "  return tf.sqrt(tf.matmul(s, tf.transpose(s)))\n",
    "\n",
    "with tf.Session() as sess:\n",
    "  fake_data = tf.constant([\n",
    "      [5.0, 3.0, 7.1],\n",
    "      [2.3, 4.1, 4.8],\n",
    "      [2.8, 4.2, 5.6],\n",
    "      [2.9, 8.3, 7.3]\n",
    "    ])\n",
    "  print(sess.run(some_method(fake_data)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def some_method(data):\n",
    "  a = data[:,0:2]\n",
    "  print(a.get_shape())\n",
    "  c = data[:,1]\n",
    "  print(c.get_shape())\n",
    "  s = (a + c)\n",
    "  return tf.sqrt(tf.matmul(s, tf.transpose(s)))\n",
    "\n",
    "with tf.Session() as sess:\n",
    "  fake_data = tf.constant([\n",
    "      [5.0, 3.0, 7.1],\n",
    "      [2.3, 4.1, 4.8],\n",
    "      [2.8, 4.2, 5.6],\n",
    "      [2.9, 8.3, 7.3]\n",
    "    ])\n",
    "  print(sess.run(some_method(fake_data)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def some_method(data):\n",
    "  a = data[:,0:2]\n",
    "  print(a.get_shape())\n",
    "  c = data[:,1:3]\n",
    "  print(c.get_shape())\n",
    "  s = (a + c)\n",
    "  return tf.sqrt(tf.matmul(s, tf.transpose(s)))\n",
    "\n",
    "with tf.Session() as sess:\n",
    "  fake_data = tf.constant([\n",
    "      [5.0, 3.0, 7.1],\n",
    "      [2.3, 4.1, 4.8],\n",
    "      [2.8, 4.2, 5.6],\n",
    "      [2.9, 8.3, 7.3]\n",
    "    ])\n",
    "  print(sess.run(some_method(fake_data)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "\n",
    "x = tf.constant([[3, 2],\n",
    "                 [4, 5],\n",
    "                 [6, 7]])\n",
    "print(\"x.shape\", x.shape)\n",
    "expanded = tf.expand_dims(x, 1)\n",
    "print(\"expanded.shape\", expanded.shape)\n",
    "sliced = tf.slice(x, [0, 1], [2, 1])\n",
    "print(\"sliced.shape\", sliced.shape)\n",
    "\n",
    "with tf.Session() as sess:\n",
    "  print(\"expanded: \", expanded.eval())\n",
    "  print(\"sliced: \", sliced.eval())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Vector vs scalar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def some_method(data):\n",
    "  print(data.get_shape())\n",
    "  a = data[:,0:2]\n",
    "  print(a.get_shape())\n",
    "  c = data[:,1:3]\n",
    "  print(c.get_shape())\n",
    "  s = (a + c)\n",
    "  return tf.sqrt(tf.matmul(s, tf.transpose(s)))\n",
    "\n",
    "with tf.Session() as sess:\n",
    "  fake_data = tf.constant([5.0, 3.0, 7.1])\n",
    "  print(sess.run(some_method(fake_data)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def some_method(data):\n",
    "  print(data.get_shape())\n",
    "  a = data[:,0:2]\n",
    "  print(a.get_shape())\n",
    "  c = data[:,1:3]\n",
    "  print(c.get_shape())\n",
    "  s = (a + c)\n",
    "  return tf.sqrt(tf.matmul(s, tf.transpose(s)))\n",
    "\n",
    "with tf.Session() as sess:\n",
    "  fake_data = tf.constant([5.0, 3.0, 7.1])\n",
    "  fake_data = tf.expand_dims(fake_data, 0)\n",
    "  print(sess.run(some_method(fake_data)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Type error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def some_method(a, b):\n",
    "  s = (a + b)\n",
    "  return tf.sqrt(tf.matmul(s, tf.transpose(s)))\n",
    "\n",
    "with tf.Session() as sess:\n",
    "  fake_a = tf.constant([\n",
    "      [5.0, 3.0, 7.1],\n",
    "      [2.3, 4.1, 4.8],\n",
    "    ])\n",
    "  fake_b = tf.constant([\n",
    "      [2, 4, 5],\n",
    "      [2, 8, 7]\n",
    "    ])\n",
    "  print(sess.run(some_method(fake_a, fake_b)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def some_method(a, b):\n",
    "  b = tf.cast(b, tf.float32)\n",
    "  s = (a + b)\n",
    "  return tf.sqrt(tf.matmul(s, tf.transpose(s)))\n",
    "\n",
    "with tf.Session() as sess:\n",
    "  fake_a = tf.constant([\n",
    "      [5.0, 3.0, 7.1],\n",
    "      [2.3, 4.1, 4.8],\n",
    "    ])\n",
    "  fake_b = tf.constant([\n",
    "      [2, 4, 5],\n",
    "      [2, 8, 7]\n",
    "    ])\n",
    "  print(sess.run(some_method(fake_a, fake_b)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# TensorFlow debugger\n",
    "\n",
    "Wrap your normal Session object with tf_debug.LocalCLIDebugWrapperSession"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow.python import debug as tf_debug\n",
    "\n",
    "def some_method(a, b):\n",
    "  b = tf.cast(b, tf.float32)\n",
    "  s = (a / b)\n",
    "  s2 = tf.matmul(s, tf.transpose(s))\n",
    "  return tf.sqrt(s2)\n",
    "\n",
    "with tf.Session() as sess:\n",
    "  fake_a = [\n",
    "      [5.0, 3.0, 7.1],\n",
    "      [2.3, 4.1, 4.8],\n",
    "    ]\n",
    "  fake_b = [\n",
    "      [2, 0, 5],\n",
    "      [2, 8, 7]\n",
    "    ]\n",
    "  a = tf.placeholder(tf.float32, shape=[2, 3])\n",
    "  b = tf.placeholder(tf.int32, shape=[2, 3])\n",
    "  k = some_method(a, b)\n",
    "  \n",
    "  # Note: won't work without the ui_type=\"readline\" argument because\n",
    "  # Datalab is not an interactive terminal and doesn't support the default \"curses\" ui_type.\n",
    "  # If you are running this a standalone program, omit the ui_type parameter and add --debug\n",
    "  # when invoking the TensorFlow program\n",
    "  #      --debug (e.g: python debugger.py --debug )\n",
    "  sess = tf_debug.LocalCLIDebugWrapperSession(sess, ui_type=\"readline\")\n",
    "  sess.add_tensor_filter(\"has_inf_or_nan\", tf_debug.has_inf_or_nan)\n",
    "  print(sess.run(k, feed_dict = {a: fake_a, b: fake_b}))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the tfdbg> window that comes up, try the following:\n",
    "* run -f has_inf_or_nan\n",
    "* Notice that several tensors are dumped once the filter criterion is met\n",
    "* List the inputs to a specific tensor:\n",
    "* li transpose:0 \n",
    "* Print the value of a tensor\n",
    "* pt transpose:0\n",
    "* Where is the inf?\n",
    "\n",
    "Visit https://www.tensorflow.org/programmers_guide/debugger for usage details of tfdbg"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## tf.Print()\n",
    "Create a python script named debugger.py with the contents shown below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%writefile debugger.py\n",
    "import tensorflow as tf\n",
    "\n",
    "def some_method(a, b):\n",
    "  b = tf.cast(b, tf.float32)\n",
    "  s = (a / b)\n",
    "  print_ab = tf.Print(s, [a, b])\n",
    "  s = tf.where(tf.is_nan(s), print_ab, s)\n",
    "  return tf.sqrt(tf.matmul(s, tf.transpose(s)))\n",
    "\n",
    "with tf.Session() as sess:\n",
    "  fake_a = tf.constant([\n",
    "      [5.0, 3.0, 7.1],\n",
    "      [2.3, 4.1, 4.8],\n",
    "    ])\n",
    "  fake_b = tf.constant([\n",
    "      [2, 0, 5],\n",
    "      [2, 8, 7]\n",
    "    ])\n",
    "  \n",
    "  print(sess.run(some_method(fake_a, fake_b)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Execute the python script"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "python debugger.py"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
